﻿using MySqlSugar;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;

namespace CodeMaker
{
    public class maker 
    {

        public void Init()
        {
            var swa = new Stopwatch();
            swa.Start();
            Console.WriteLine("启动BaseMaker.Init");
            Console.WriteLine("生成文件结构开始...");
            string BaseNname = "JinFanCode" + DateTime.Now.ToString("yyyyMMddHHmmss");
            Directory.CreateDirectory("C:/" + BaseNname);
            Directory.CreateDirectory("C:/" + BaseNname + "/Repositories");
            Directory.CreateDirectory("C:/" + BaseNname + "/Repositories/Repository");
            Directory.CreateDirectory("C:/" + BaseNname + "/Repositories/IRepository");
            Directory.CreateDirectory("C:/" + BaseNname + "/Services");
            Directory.CreateDirectory("C:/" + BaseNname + "/Services/Service");
            Directory.CreateDirectory("C:/" + BaseNname + "/Services/IService");
            Directory.CreateDirectory("C:/" + BaseNname + "/Models");
            Console.WriteLine("生成文件结构结束...");
            Console.WriteLine("===============================================");
            Console.WriteLine("遍历生成开始...");
            var db = SugarDao.GetInstance();
            var isLog = db.IsEnableLogEvent;
            db.IsEnableLogEvent = false;
            string sql = "select table_name as name from information_schema.tables where table_schema='jinfan' and table_name<>'__efmigrationshistory'";
            var tables = db.GetDataTable(sql);

            string StartupAll = "";
            string MplistAll = "";
            if (tables != null && tables.Rows.Count > 0)
            {
                foreach (DataRow dr in tables.Rows)
                {
                    var sw = new Stopwatch();
                    sw.Start();
                    string tableName = dr["name"].ToString().Substring(0, 1).ToUpper() + dr["name"].ToString().Substring(1);
                    var currentTable = db.GetDataTable(string.Format("select * from {0} limit 0,1", new ClassGenerating().GetTableNameWithSchema(db, tableName).GetTranslationSqlName()));

                    var tableColumns = new ClassGenerating().GetTableColumns(db, tableName);
                    string className = tableName;
                    var classCode = new ClassGenerating().DataTableToClass(currentTable, className + "Model", "Models", tableColumns);
                    CreateFile("C:\\" + BaseNname + "\\Models\\" + className + "Model.cs", classCode, Encoding.UTF8);

                    CreateFile("C:\\" + BaseNname + "\\Repositories\\Repository\\" + className + "Repository.cs", RepositoryTemplate.Replace("xxxxxRepository", className + "Repository").Replace("xxxxx", className + "Model"), Encoding.UTF8);
                    CreateFile("C:\\" + BaseNname + "\\Repositories\\IRepository\\I" + className + "Repository.cs", IRepositoryTemplate.Replace("xxxxxRepository", className + "Repository").Replace("xxxxx", className + "Model"), Encoding.UTF8);


                    CreateFile("C:\\" + BaseNname + "\\Services\\Service\\" + className + "Service.cs", ServiceTemplate.Replace("xxxxxRepository", className + "Repository").Replace("xxxxxService", className + "Service").Replace("xxxxx", className + "Model"), Encoding.UTF8);
                    CreateFile("C:\\" + BaseNname + "\\Services\\IService\\I" + className + "Service.cs", IServiceTemplate.Replace("xxxxxRepository", className + "Repository").Replace("xxxxxService", className + "Service").Replace("xxxxx", className + "Model"), Encoding.UTF8);
                    sw.Stop();
                    Console.WriteLine("遍历生成（耗时：" + sw.Elapsed + "） ====》" + className);
                    MplistAll += MpListTemplate.Replace("zzzzz", className);
                    StartupAll += StartupTemplate.Replace("xxxxx", className);
                }
            }
            db.IsEnableLogEvent = isLog;
            Console.WriteLine("遍历生成结束...");
            Console.WriteLine("生成SugarDao.cs");
            CreateFile("C:\\" + BaseNname + "\\Repositories\\SugarDao.cs", SugarDaoTemplate.Replace("yyyyy", MplistAll.Substring(0, MplistAll.Length - 1)).Replace("wwwww", LogEventStarting), Encoding.UTF8);
            Console.WriteLine("生成Startup注入代码");
            CreateFile("C:\\" + BaseNname + "\\Startup.cs", StartupAll, Encoding.UTF8);
            Console.WriteLine("==========================================================================================");
            Console.WriteLine("  ");
            Console.WriteLine("源码地址(总耗时：" + swa.Elapsed + ")====》  C:/ " + BaseNname + "  《====");
            Console.WriteLine("  ");
            Console.WriteLine("==========================================================================================");

        }

        #region 文件操作
        /// <summary>
        /// 创建一个文件,并将字符串写入文件。
        /// </summary>
        /// <param name="filePath">文件的绝对路径</param>
        /// <param name="text">字符串数据</param>
        /// <param name="encoding">字符编码</param>
        public static void CreateFile(string filePath, string text, Encoding encoding)
        {
            try
            {
                //如果文件不存在则创建该文件
                if (!IsExistFile(filePath))
                {
                    //获取文件目录路径
                    string directoryPath = GetDirectoryFromFilePath(filePath);

                    //如果文件的目录不存在，则创建目录
                    CreateDirectory(directoryPath);

                    //创建文件
                    FileInfo file = new FileInfo(filePath);
                    using (FileStream stream = file.Create())
                    {
                        using (StreamWriter writer = new StreamWriter(stream, encoding))
                        {
                            //写入字符串     
                            writer.Write(text);

                            //输出
                            writer.Flush();
                        }
                    }
                }
            }
            catch
            {
            }
        }
        /// <summary>
        /// 检测指定文件是否存在,如果存在则返回true。
        /// </summary>
        /// <param name="filePath">文件的绝对路径</param>        
        public static bool IsExistFile(string filePath)
        {
            return File.Exists(filePath);
        }
        /// <summary>
        /// 从文件绝对路径中获取目录路径
        /// </summary>
        /// <param name="filePath">文件的绝对路径</param>
        public static string GetDirectoryFromFilePath(string filePath)
        {
            //实例化文件
            FileInfo file = new FileInfo(filePath);

            //获取目录信息
            DirectoryInfo directory = file.Directory;

            //返回目录路径
            return directory.FullName;
        }
        /// <summary>
        /// 创建一个目录
        /// </summary>
        /// <param name="directoryPath">目录的绝对路径</param>
        public static void CreateDirectory(string directoryPath)
        {
            //如果目录不存在则创建该目录
            if (!IsExistDirectory(directoryPath))
            {
                Directory.CreateDirectory(directoryPath);
            }
        }
        /// <summary>
        /// 检测指定目录是否存在
        /// </summary>
        /// <param name="directoryPath">目录的绝对路径</param>        
        public static bool IsExistDirectory(string directoryPath)
        {
            return Directory.Exists(directoryPath);
        }
        #endregion

        #region Repository类模版
        public string RepositoryTemplate =
@"using Models;
using MySqlSugar;
using Repositories.IRepository;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

namespace Repositories.Repository
{
    public class xxxxxRepository : IxxxxxRepository
    {
        protected readonly SqlSugarClient _db;
        public xxxxxRepository()
        {
            _db = SugarDao.GetInstance();
        }

        #region 查询

        /// <summary>
        /// 查询单条根据主键
        /// </summary>
        public xxxxx GetById(int? id)
        {
            var model = _db.Queryable<xxxxx>().InSingle(id);
            return model;
        }

        /// <summary>
        /// 查询所有
        /// </summary>
        public Queryable<xxxxx> GetList()
        {
            return _db.Queryable<xxxxx>();
        }

        /// <summary>
        /// 根据条件查询
        /// </summary>
        public Queryable<xxxxx> GetList(Expression<Func<xxxxx, bool>> where)
        {
            return _db.Queryable<xxxxx>().Where(where);
        }

        /// <summary>
        /// 按页查询 OrderFields string 支持复杂【id desc,name asc】
        /// </summary>
        public Queryable<xxxxx> GetPageList(Expression<Func<xxxxx, bool>> where, int pageIndex, int pageSize, string OrderFields)
        {
            return _db.Queryable<xxxxx>().Where(where).OrderBy(it => it.Id, OrderByType.desc).Skip((pageIndex - 1) * pageSize).Take(pageSize);
        }
#endregion

        #region 删除
        /// <summary>
        /// 根据主键删除
        /// </summary>
        public bool DeleteById(int id)
        {
            return _db.Delete<xxxxx, int>(id);
        }

        /// <summary>
        /// 根据主键组批量删除
        /// </summary>
        public bool DeleteById(int[] ids)
        {
            return _db.Delete<xxxxx, int>(ids);
        }

        /// <summary>
        /// 根据实体删除【一定要带主键！！！】
        /// </summary>
        public bool DeleteByModel(xxxxx model)
        {
            return _db.Delete(model);
        }

        #endregion

        #region 新增
        /// <summary>
        /// 强制新增，不管主键
        /// </summary>
        public int Insert(xxxxx model)
        {
            return int.Parse(_db.Insert(model).ToString());
        }

        /// <summary>
        /// 批量插入 适合海量数据插入
        /// </summary>
        public bool InsertRange(List<xxxxx> list)
        {
            return _db.SqlBulkCopy(list);
        }

        #endregion

        #region 修改
        /// <summary>
        /// 根据实体更新【主键一定要有！！！】
        /// </summary>
        public bool Update(xxxxx model)
        {
            return _db.Update(model);
        }

        /// <summary>
        /// 10条以上批量更新
        /// </summary>
        public bool UpdateRange(List<xxxxx> list)
        {
            return _db.SqlBulkReplace(list);
        }
        #endregion
    }
}

";
        #endregion

        #region IRepository类模板
        public string IRepositoryTemplate =
@"using Models;
using MySqlSugar;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;

namespace Repositories.IRepository
{
    public interface IxxxxxRepository
    {
        #region 查询

        /// <summary>
        /// 查询单条根据主键
        /// </summary>
        xxxxx GetById(int? id);

        /// <summary>
        /// 查询所有
        /// </summary>
        Queryable<xxxxx> GetList();

        /// <summary>
        /// 根据条件查询
        /// </summary>
        Queryable<xxxxx> GetList(Expression<Func<xxxxx, bool>> where);

        /// <summary>
        /// 按页查询
        /// </summary>
        Queryable<xxxxx> GetPageList(Expression<Func<xxxxx, bool>> where, int pageIndex, int pageSize, string OrderFields);
        #endregion

        #region 删除
        /// <summary>
        /// 根据主键删除
        /// </summary>
        bool DeleteById(int id);

        /// <summary>
        /// 根据主键组批量删除
        /// </summary>
        bool DeleteById(int[] ids);

        /// <summary>
        /// 根据实体删除【一定要带主键！！！】
        /// </summary>
        bool DeleteByModel(xxxxx model);

        #endregion

        #region 新增
        /// <summary>
        /// 强制新增，不管主键
        /// </summary>
        int Insert(xxxxx model);

        /// <summary>
        /// 批量插入 适合海量数据插入
        /// </summary>
        bool InsertRange(List<xxxxx> list);

        #endregion

        #region 修改
        /// <summary>
        /// 根据实体更新【主键一定要有！！！】
        /// </summary>
        bool Update(xxxxx model);

        /// <summary>
        /// 10条以上批量更新
        /// </summary>
        bool UpdateRange(List<xxxxx> list);
        #endregion
    }
}
";
        #endregion

        #region Service类模板

        public string ServiceTemplate =
            @"using System;
using System.Collections.Generic;
using System.Text;
using Models;
using Repositories;
using Services.IService;
using Repositories.IRepository;
using MySqlSugar;
using System.Linq.Expressions;

namespace Services.Service
{
    public class xxxxxService : IxxxxxService
    {

        private readonly IxxxxxRepository _repository;
        public xxxxxService(IxxxxxRepository repository)
        {
            _repository = repository;
        }

        #region 查询

        /// <summary>
        /// 查询单条根据主键
        /// </summary>
        /// <returns></returns>
        public xxxxx GetById(int? id)
        {
            return _repository.GetById(id);
        }

        /// <summary>
        /// 查询所有
        /// </summary>
        /// <returns></returns>
        public List<xxxxx> GetList()
        {
            return _repository.GetList().ToList();
        }

        /// <summary>
        /// 根据条件查询
        /// </summary>
        /// <returns></returns>
        public List<xxxxx> GetList(Expression<Func<xxxxx, bool>> where)
        {
            return _repository.GetList(where).ToList();
        }

        /// <summary>
        /// 按页查询
        /// </summary>
        public List<xxxxx> GetPageList(Expression<Func<xxxxx, bool>> where, int pageIndex, int pageSize, string OrderFields)
        {
            return _repository.GetPageList(where, pageIndex, pageSize, OrderFields).ToList();
        }
        #endregion

        #region 删除
        /// <summary>
        /// 根据主键删除
        /// </summary>
        public bool DeleteById(int id)
        {
            return _repository.DeleteById(id);
        }

        /// <summary>
        /// 根据主键组批量删除
        /// </summary>
        public bool DeleteById(int[] ids)
        {
            return _repository.DeleteById(ids);
        }

        /// <summary>
        /// 根据实体删除【一定要带主键！！！】
        /// </summary>
        public bool DeleteByModel(xxxxx model)
        {
            return _repository.DeleteByModel(model);
        }

        #endregion

        #region 新增
        /// <summary>
        /// 强制新增，不管主键
        /// </summary>
        public int Insert(xxxxx model)
        {
            return _repository.Insert(model);
        }

        /// <summary>
        /// 批量插入 适合海量数据插入
        /// </summary>
        public bool InsertRange(List<xxxxx> list)
        {
            return _repository.InsertRange(list);
        }

        #endregion

        #region 修改
        /// <summary>
        /// 根据实体更新【主键一定要有！！！】
        /// </summary>
        public bool Update(xxxxx model)
        {
            return _repository.Update(model);
        }

        /// <summary>
        /// 10条以上批量更新
        /// </summary>
        public bool UpdateRange(List<xxxxx> list)
        {
            return _repository.UpdateRange(list);
        }
        #endregion
    }
}
";
        #endregion

        #region IService类模板

        public string IServiceTemplate =
            @"using Models;
using MySqlSugar;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text;

namespace Services.IService
{
   public interface IxxxxxService
    {
        #region 查询

        /// <summary>
        /// 查询单条根据主键
        /// </summary>
        xxxxx GetById(int? id);

        /// <summary>
        /// 查询所有
        /// </summary>
        List<xxxxx> GetList();

        /// <summary>
        /// 根据条件查询
        /// </summary>
        List<xxxxx> GetList(Expression<Func<xxxxx, bool>> where);

        /// <summary>
        /// 按页查询
        /// </summary>
        List<xxxxx> GetPageList(Expression<Func<xxxxx, bool>> where, int pageIndex, int pageSize, string OrderFields);
        #endregion

        #region 删除
        /// <summary>
        /// 根据主键删除
        /// </summary>
        bool DeleteById(int id);

        /// <summary>
        /// 根据主键组批量删除
        /// </summary>
        bool DeleteById(int[] ids);

        /// <summary>
        /// 根据实体删除【一定要带主键！！！】
        /// </summary>
        bool DeleteByModel(xxxxx model);

        #endregion

        #region 新增
        /// <summary>
        /// 强制新增，不管主键
        /// </summary>
        int Insert(xxxxx model);

        /// <summary>
        /// 批量插入 适合海量数据插入
        /// </summary>
        bool InsertRange(List<xxxxx> list);

        #endregion

        #region 修改
        /// <summary>
        /// 根据实体更新【主键一定要有！！！】
        /// </summary>
        bool Update(xxxxx model);

        /// <summary>
        /// 10条以上批量更新
        /// </summary>
        bool UpdateRange(List<xxxxx> list);
        #endregion
    }
}
";
        #endregion

        #region SugarDaoTemplate
        public string SugarDaoTemplate =
            @"using MySqlSugar;
using System;

namespace Repositories
{
    /// <summary>
    /// SqlSugar
    /// </summary>
    public class SugarDao
    {
        //禁止实例化
        private SugarDao()
        {

        }


        //public static string ConnectionString
        //{
        //    get
        //    {
        //        string reval =;
        //        return reval;
        //    }
        //}


        /// <summary>
        /// 全局配置类
        /// </summary>
        public class SugarConfigs
        {
            //key类名 value表名
            public static List<KeyValue> MpList = new List<KeyValue>(){
                yyyyy
            };
        }

        public static SqlSugarClient GetInstance()
        {
            var db = new SqlSugarClient(Utility.SiteConfig.SiteConfigStr);
            //var db = new SqlSugarClient(sqlstr);
            db.SetMappingTables(SugarConfigs.MpList);//设置关联表 (引用地址赋值，每次赋值都只是存储一个内存地址)
            db.IsEnableLogEvent = true;//启用日志事件
            wwwww
            return db;
        }
    }
}
";
        #endregion

        #region 全局设置
        public string MpListTemplate = "new KeyValue() { Key = \"zzzzzModel\", Value = \"zzzzz\"},\n";
        public string LogEventStarting = "db.LogEventStarting = (sql, par) => { Console.WriteLine(sql + \" \" + par + \"\\r\\n\"); };";
        #endregion

        #region Startup注入模板
        public string StartupTemplate = @"
            services.AddScoped<IxxxxxRepository, xxxxxRepository>();
            services.AddScoped<IxxxxxService, xxxxxService>();";
        #endregion

    }
}
